package cn.stylefeng.guns.modular.business.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.guns.modular.business.comment.YunHeKey;
import cn.stylefeng.guns.modular.business.entity.RiverInfo;
import cn.stylefeng.guns.modular.business.entity.SubDic;
import cn.stylefeng.guns.modular.business.enums.RiverInfoExceptionEnum;
import cn.stylefeng.guns.modular.business.mapper.RiverInfoMapper;
import cn.stylefeng.guns.modular.business.pojo.RiverInfoRequest;
import cn.stylefeng.guns.modular.business.service.RiverInfoService;
import cn.stylefeng.guns.modular.business.service.SubUseBrowseService;
import cn.stylefeng.roses.kernel.auth.api.LoginUserApi;
import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser;
import cn.stylefeng.roses.kernel.db.api.factory.PageFactory;
import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
import cn.stylefeng.roses.kernel.rule.util.HttpServletUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 河道信息表业务实现层
 *
 * @author zhangyaowen
 * @date 2021/10/08 16:51
 */
@Service
public class RiverInfoServiceImpl extends ServiceImpl<RiverInfoMapper, RiverInfo> implements RiverInfoService {

    @Resource
    private LoginUserApi loginUserApi;
    @Resource
    private SubUseBrowseService subUseBrowseService;

	@Override
    public void add(RiverInfoRequest riverInfoRequest) {
        RiverInfo riverInfo = new RiverInfo();
        BeanUtil.copyProperties(riverInfoRequest, riverInfo);
        this.save(riverInfo);
    }

    @Override
    public void del(RiverInfoRequest riverInfoRequest) {
        RiverInfo riverInfo = this.queryRiverInfo(riverInfoRequest);
        this.removeById(riverInfo.getId());
    }

    @Override
    public void edit(RiverInfoRequest riverInfoRequest) {
        RiverInfo riverInfo = this.queryRiverInfo(riverInfoRequest);
        BeanUtil.copyProperties(riverInfoRequest, riverInfo);
        this.updateById(riverInfo);
    }

    @Override
    public RiverInfo detail(RiverInfoRequest riverInfoRequest) {
        return this.queryRiverInfo(riverInfoRequest);
    }

    @Override
    public PageResult<RiverInfo> findPage(RiverInfoRequest riverInfoRequest) {
        LambdaQueryWrapper<RiverInfo> wrapper = createWrapper(riverInfoRequest);
        Page<RiverInfo> sysRolePage = this.page(PageFactory.defaultPage(), wrapper);
        return PageResultFactory.createPageResult(sysRolePage);
    }

    @Override
    public List<RiverInfo> findList(RiverInfoRequest riverInfoRequest) {
        LambdaQueryWrapper<RiverInfo> wrapper = this.createWrapper(riverInfoRequest);
        return this.list(wrapper);
    }

    /**
     * 获取信息
     *
     * @author zhangyaowen
     * @date 2021/10/08 16:51
     */
    private RiverInfo queryRiverInfo(RiverInfoRequest riverInfoRequest) {
        RiverInfo riverInfo = this.getById(riverInfoRequest.getId());
        if (ObjectUtil.isEmpty(riverInfo)) {
            throw new ServiceException(RiverInfoExceptionEnum.RIVERINFO_NOT_EXISTED);
        }
        return riverInfo;
    }

    /**
     * 创建查询wrapper
     *
     * @author zhangyaowen
     * @date 2021/10/08 16:51
     */
    private LambdaQueryWrapper<RiverInfo> createWrapper(RiverInfoRequest riverInfoRequest) {
        LambdaQueryWrapper<RiverInfo> queryWrapper = new LambdaQueryWrapper<>();

        Long id = riverInfoRequest.getId();
        String riverName = riverInfoRequest.getRiverName();
        String riverCode = riverInfoRequest.getRiverCode();
        String riverForm = riverInfoRequest.getRiverForm();
        String riverTown = riverInfoRequest.getRiverTown();
        String riverProvince = riverInfoRequest.getRiverProvince();
        String historyDating = riverInfoRequest.getHistoryDating();
        String theCommon = riverInfoRequest.getTheCommon();
        String startSite = riverInfoRequest.getStartSite();
        String endSite = riverInfoRequest.getEndSite();
        String riverLabel = riverInfoRequest.getRiverLabel();
        String riverIntroduce = riverInfoRequest.getRiverIntroduce();
        String riverActuality = riverInfoRequest.getRiverActuality();

        queryWrapper.eq(ObjectUtil.isNotNull(id), RiverInfo::getId, id);
        queryWrapper.like(ObjectUtil.isNotEmpty(riverName), RiverInfo::getRiverName, riverName);
        queryWrapper.like(ObjectUtil.isNotEmpty(riverCode), RiverInfo::getRiverCode, riverCode);
        queryWrapper.like(ObjectUtil.isNotEmpty(riverForm), RiverInfo::getRiverForm, riverForm);
        queryWrapper.like(ObjectUtil.isNotEmpty(riverTown), RiverInfo::getRiverTown, riverTown);
        queryWrapper.like(ObjectUtil.isNotEmpty(riverProvince), RiverInfo::getRiverProvince, riverProvince);
        queryWrapper.like(ObjectUtil.isNotEmpty(historyDating), RiverInfo::getHistoryDating, historyDating);
        queryWrapper.like(ObjectUtil.isNotEmpty(theCommon), RiverInfo::getTheCommon, theCommon);
        queryWrapper.like(ObjectUtil.isNotEmpty(startSite), RiverInfo::getStartSite, startSite);
        queryWrapper.like(ObjectUtil.isNotEmpty(endSite), RiverInfo::getEndSite, endSite);
        queryWrapper.like(ObjectUtil.isNotEmpty(riverLabel), RiverInfo::getRiverLabel, riverLabel);
        queryWrapper.like(ObjectUtil.isNotEmpty(riverIntroduce), RiverInfo::getRiverIntroduce, riverIntroduce);
        queryWrapper.like(ObjectUtil.isNotEmpty(riverActuality), RiverInfo::getRiverActuality, riverActuality);

        return queryWrapper;
    }

    @Override
    public List<Map<String, Object>> toReview(String riverName) {
        HttpServletRequest request = HttpServletUtil.getRequest();
        Long userid;
        if (ObjectUtil.isNotNull(request)) {

            LoginUser loginUser = loginUserApi.getLoginUser();
            userid = loginUser.getUserId();
        } else {
            throw new ServiceException(RiverInfoExceptionEnum.REQUEST_EMPTY);
        }
        LambdaQueryWrapper<RiverInfo> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(ObjectUtil.isNotEmpty(riverName), RiverInfo::getRiverName, riverName);
        List<RiverInfo> riverInfoList = this.list(queryWrapper);
        if(userid != 0l && userid != -1l) {
            subUseBrowseService.saveBrowse(YunHeKey.HEDAO,riverInfoList.get(0).getRiverName(),userid,request);
        }
        List<Map<String, Object>> mapList = new ArrayList<>();
        for (RiverInfo riverInfo : riverInfoList) {

            Map<String, Object> map = new HashMap<String, Object>();
            map = JSONObject.parseObject(JSONObject.toJSONString(riverInfo), Map.class);

            // 获取类的属性
            Field[] declaredFields = RiverInfo.class.getDeclaredFields();
            List<Map<String, Object>> mplist = new ArrayList<>();
            // 遍历属性，获取属性上ApiModelProperty的值，属性的名，存入Properties
            if (declaredFields.length != 0) {

                int i = 1;
                Map<String, Object> p = new HashMap<String, Object>();
                for (Field field : declaredFields) {

                    Map<String, Object> mp = new HashMap<String, Object>();
                    if (field.getAnnotation(ApiModelProperty.class) != null) {
                        //获取注解属性
                        ApiModelProperty aa = field.getAnnotation(ApiModelProperty.class);
                        // key和value可根据需求存
                        // 这存的key为注解的值，value为类属性名
                        if ("riverIntroduce".equals(field.getName()) || "riverName".equals(field.getName()) ) {
                            p.put(field.getName(), map.get(field.getName()));
                        } else {
                            mp.put("key", aa.value());
                            mp.put("value", map.get(field.getName()));

                            if (i != 1) {
                                mplist.add(mp);
                            }
                        }
                    }
                    i++;
                }
                p.put("list", mplist);
                if (i != 1) {
                    mapList.add(p);
                }
            }
        }
        return mapList;
    }

    @Override
    public List<Map<String,Object>> findAllList(List<SubDic> riverList, List<SubDic> townList, String[] times, String name) {
        LambdaQueryWrapper<RiverInfo> wrapper = createWrappers(riverList,townList,times,name);
        List<RiverInfo>  list = this.list(wrapper);
        List<Map<String,Object>> mapList=new ArrayList<>();
        for(RiverInfo riverInfo:list) {
            Map<String, Object> map = new HashMap<String, Object>();
//            String titleOne = riverInfo.getTheCommon();
//            if("".equals(riverInfo.getTheCommon()) || riverInfo.getTheCommon()==null){
//                titleOne = riverInfo.getHistoryDating();
//            }
//            if( riverInfo.getRiverName() !=null){
//                titleOne += riverInfo.getRiverName();
//            }
            map.put("title", riverInfo.getRiverName());
            map.put("historyDating",riverInfo.getHistoryDating());
            map.put("theCommon",riverInfo.getTheCommon());
            map.put("from","中国运河志 河道工程与管理" );
            map.put("createTime",DateUtil.format(riverInfo.getCreateTime(), "yyyy-MM-dd"));
            map.put("type",YunHeKey.HDHZ );
            map.put("id",riverInfo.getRiverName());
            mapList.add(map);
        }
        return mapList;
    }
    /**
     * 创建查询wrapper
     *
     * @author zhangyaowen
     * @date 2021/08/30 10:17
     */
    private LambdaQueryWrapper<RiverInfo> createWrappers(List<SubDic> riverList, List<SubDic> townList, String[] times, String name) {
        LambdaQueryWrapper<RiverInfo> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.and(i-> i.like(ObjectUtil.isNotNull(name), RiverInfo::getRiverName, name).or()
                .like(ObjectUtil.isNotNull(name), RiverInfo::getRiverForm, name).or()
                .like(ObjectUtil.isNotNull(name), RiverInfo::getRiverIntroduce, name).or()
                .like(ObjectUtil.isNotNull(name), RiverInfo::getRiverTown, name).or()
                .like(ObjectUtil.isNotNull(name), RiverInfo::getHistoryDating, name).or()
                .like(ObjectUtil.isNotNull(name), RiverInfo::getTheCommon, name).or()
                .like(ObjectUtil.isNotNull(name), RiverInfo::getStartSite, name).or()
                .like(ObjectUtil.isNotNull(name), RiverInfo::getEndSite, name));
        if( !riverList.isEmpty()) {
            queryWrapper.and(wrapper -> {
                for (int i = 0; i < riverList.size(); i++) {
                    String dicAname = riverList.get(i).getDicAname();
                    wrapper.like(ObjectUtil.isNotEmpty(dicAname), RiverInfo::getRiverName, dicAname).or()
                            .like(ObjectUtil.isNotEmpty(dicAname), RiverInfo::getRiverForm, dicAname);
                    if (i != riverList.size() - 1) {
                        wrapper.or();
                    }
                }
            });
        }
        if( !townList.isEmpty()) {
            queryWrapper.and(wrapper -> {
                for (int i = 0; i < townList.size(); i++) {
                    String dicZname = townList.get(i).getDicZname();
                    String dicAname = townList.get(i).getDicAname();
                    wrapper.like(ObjectUtil.isNotEmpty(dicZname), RiverInfo::getRiverTown, dicZname).or()
                            .like(ObjectUtil.isNotEmpty(dicAname), RiverInfo::getStartSite, dicAname)
                            .like(ObjectUtil.isNotEmpty(dicAname), RiverInfo::getEndSite, dicAname);
                    if (i != townList.size() - 1) {
                        wrapper.or();
                    }
                }
            });
        }
        if( times.length !=0) {
            queryWrapper.and(wrapper -> {
                for (int i = 0; i < times.length; i++) {
                    String time = times[i];
                    wrapper.like(ObjectUtil.isNotEmpty(time), RiverInfo::getHistoryDating, time).or()
                            .like(ObjectUtil.isNotEmpty(time), RiverInfo::getTheCommon, time);
                    if (i != times.length - 1) {
                        wrapper.or();
                    }
                }
            });
        }
        return queryWrapper;
    }
}